package com.yhh;

import com.yhh.Entity.Command;
import com.yhh.Entity.HandlerCommand;
import com.yhh.Entity.MyFile;
import com.yhh.Entity.MyFileFactory;
import com.yhh.Exceptions.InstructionException;
import com.yhh.Exceptions.NonInstructionException;
import com.yhh.myUtils.myStringUtils;

import java.io.*;
import java.net.Socket;
import java.util.Date;
import java.util.Map;

import static com.yhh.Pipeline.directory;
import static com.yhh.Pipeline.pipeline;
import static com.yhh.myUtils.CommandUtils.hasFile;

class SendCommand extends Command implements HandlerCommand {
    private static final String c = "send";

    private FileOutputStream fos;

    public SendCommand(Socket socket) {
        super(socket);
        command.add("send");
        command.add("-d");
        command.add("-t");
        command.add("-f");
    }

    @Override
    public void handlerCommand(Map<String, String> args) throws InstructionException, NonInstructionException {
        handlerSend(args);
        ServerThread.save();
    }
    @Override
    public void handlerParameter(Map<String, String> args) throws InstructionException, NonInstructionException {
        if (args.get("-f") == null) {
            throw new InstructionException("send指令需要一个-f参数", "-f");
        }
    }

    @Override
    public boolean check(Map<String, String> args) throws NonInstructionException, InstructionException {
        handlerParameter(args);
        checkParameter(args);
        return true;
    }
    public void handlerSend(Map<String, String> args) {
        try {
            //发送可以接受标志
            sendMsg("ready");
            //返回密钥
            String _m = handlerSendCommand(args);
            sendMsg(_m);
        } catch (NumberFormatException e) {
            sendMsg("错误的时间格式");
        } catch (Exception e) {
            sendMsg("错误");
        }

    }

    private String handlerSendCommand(Map<String, String> args) {
        MyFile _file;
        try {
            //根据参数生成文件对象
            _file = MyFileFactory.executeSend(args);
            //设置ip
            _file.setIp(socket.getInetAddress().toString());
            //设置上一次操作ip
            _file.setLastIp(socket.getInetAddress().toString());

            DataInputStream dis = new DataInputStream(socket.getInputStream());

            // 文件名和长度
            String fileName = dis.readUTF();

            _file.setFilePath(fileName);

            long fileLength = dis.readLong();

            if (!directory.exists()) {
                if (!directory.mkdir()) {
                    throw new RuntimeException();
                }
            }

            File file = new File(directory.getAbsolutePath() + File.separatorChar + fileName);

            fos = new FileOutputStream(file);
            // 开始接收文件
            byte[] bytes = new byte[1024];

            int length;

            while ((length = dis.read(bytes, 0, bytes.length)) != -1) {
                fileLength -= length;
                fos.write(bytes, 0, length);
                fos.flush();
                if (fileLength <= 0) break;
            }

            System.out.println("======== 文件接收成功 [File Name：" + fileName + "] [ip：" + socket.getInetAddress() + "] ========");

            // 获取输出流，响应客户端的请求
            String randomString = myStringUtils.getRandomString(10);

            //获取不重复的key
            while (pipeline.get(randomString) != null) randomString = myStringUtils.getRandomString(10);

            _file.setKey(randomString);
            //删除map中同名的记录
            pipeline.forEach((key, myfile) -> {
                if (myfile.getFilePath().equals(fileName)) pipeline.remove(key);
            });
            //将键值对放入map中，receive时需要根据字符串查找相应文件
            pipeline.put(randomString, _file);

            return "您的密钥为: " + randomString;
        } catch (Exception e) {
            e.printStackTrace();
            return "发生了错误。";
        } finally {
            try {
                if (fos != null)
                    fos.close();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }




}
